package io.shuttle.mbe.api

import io.shuttle.mbe.api.types.Value1Function
import io.shuttle.mbe.api.types.VoidFunction
import io.shuttle.mbe.core.Promise

////////////////////
// Offscreen
////////////////////
/**
 * Use the `offscreen` API to create and manage offscreen documents.
 *
 * Permissions: "offscreen"
 * @since Chrome 109, MV3
 */
interface Offscreen {
    /**
     * Creates a new offscreen document for the extension.
     * @param parameters The parameters describing the offscreen document to create.
     * @return The `createDocument` method provides its result via callback or returned as a `Promise` (MV3 only).
     */
    fun createDocument(parameters: CreateParameters): Promise<Void>

    /**
     * Creates a new offscreen document for the extension.
     * @param parameters The parameters describing the offscreen document to create.
     * @param callback Invoked when the offscreen document is created and has completed its initial page load.
     */
    fun createDocument(parameters: CreateParameters, callback: VoidFunction)

    /**
     * Closes the currently-open offscreen document for the extension.
     * @return The `closeDocument` method provides its result via callback or returned as a `Promise` (MV3 only).
     */
    fun closeDocument(): Promise<Void>

    /**
     * Closes the currently-open offscreen document for the extension.
     * @param callback Invoked when the offscreen document has been closed.
     */
    fun closeDocument(callback: VoidFunction)

    /**
     * Determines whether the extension has an active document.
     * @return The `hasDocument` method provides its result via callback or returned as a `Promise` (MV3 only).
     */
    fun hasDocument(): Promise<Boolean>;

    /**
     * Determines whether the extension has an active document.
     * @param callback Invoked with the result of whether the extension has an active offscreen document.
     */
    fun hasDocument(callback: Value1Function<Boolean>? = null)

    /** The reason(s) the extension is creating the offscreen document. */
    enum class Reason {
        /** A reason used for testing purposes only. */
        TESTING,

        /** The offscreen document is responsible for playing audio. */
        AUDIO_PLAYBACK,

        /** The offscreen document needs to embed and script an iframe in order to modify the iframe's content. */
        IFRAME_SCRIPTING,

        /** The offscreen document needs to embed an iframe and scrape its DOM to extract information. */
        DOM_SCRAPING,

        /** The offscreen document needs to interact with Blob objects (including URL.createObjectURL()). */
        BLOBS,

        /** The offscreen document needs to use the DOMParser API. */
        DOM_PARSER,

        /** The offscreen document needs to interact with media streams from user media (e.g. getUserMedia()). */
        USER_MEDIA,

        /** The offscreen document needs to interact with media streams from display media (e.g. getDisplayMedia()). */
        DISPLAY_MEDIA,

        /** The offscreen document needs to use WebRTC APIs. */
        WEB_RTC,

        /** The offscreen document needs to interact with the clipboard APIs(e.g. Navigator.clipboard). */
        CLIPBOARD,

        /** Specifies that the offscreen document needs access to localStorage. */
        LOCAL_STORAGE,

        /** Specifies that the offscreen document needs to spawn workers. */
        WORKERS,

        /** Specifies that the offscreen document needs to use navigator.getBattery. */
        BATTERY_STATUS,

        /** Specifies that the offscreen document needs to use window.matchMedia. */
        MATCH_MEDIA,

        /** Specifies that the offscreen document needs to use navigator.geolocation. */
        GEOLOCATION,
    }

    /** The parameters describing the offscreen document to create. */
    data class CreateParameters(
        /** The reason(s) the extension is creating the offscreen document. */
        var reason: Reason,
        /** The (relative) URL to load in the document. */
        var url: String,
        /** A developer-provided string that explains, in more detail, the need for the background context. The user agent _may_ use this in display to the user. */
        var justification: String
    )
}